#!/usr/bin/python

"""
Copyright 2008 Israel Garcia

This file is part of Audlib.
Audlib is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
any later version.

Audlib is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Audlib.  If not, see <http://www.gnu.org/licenses/>.
"""

import adminbase, dbus, gtk.glade, mediamanager, os, os.path
from gnomevfs import get_local_path_from_uri

class AddWindow:
    def __init__(self, mainwin, title=None, parent=None, action=gtk.FILE_CHOOSER_ACTION_OPEN, buttons=(gtk.STOCK_OPEN, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)):
        self.dialog = gtk.FileChooserDialog(title, parent, action, buttons)
        self.dialog.set_default_response(gtk.RESPONSE_OK)
        self.dialog.set_select_multiple(True)
        self.mainwin = mainwin
        response = self.dialog.run()
        if response == gtk.RESPONSE_OK:
            if action==gtk.FILE_CHOOSER_ACTION_OPEN:
                uri_list = self.dialog.get_uris()
                self.dialog.destroy()
                tags_list = mediamanager.TagsDiscoverer(uri_list).get_tags()
                adminbase.insert_info(tags_list)
                mainwin.import_data(tags_list)
            elif action==gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER:
                dir_names = self.dialog.get_filenames() # Todo: implement gVFS and use uris here
                self.dialog.destroy()
                self._import_dirs(dir_names)
        elif response == gtk.RESPONSE_CANCEL:
            print 'canceled'
        self.dialog.destroy()
    
    def _add_files_in_dir(self, dirpath, filenames):
            files_uris = ['file://' + os.path.join(dirpath, name) for name in filenames]
            tags_list = mediamanager.TagsDiscoverer(files_uris).get_tags()
            adminbase.insert_info(tags_list)
            self.mainwin.import_data(tags_list)

    def _import_dirs(self, dir_uris):
        for folder in dir_uris:
            for dirpath, dirnames, filenames in os.walk(folder, topdown = False):
                self._add_files_in_dir(dirpath, filenames)

class MainWindow:
    def __init__(self):
        self.xml = gtk.glade.XML('mlib.glade')
        self.tv = self.xml.get_widget('search_results_tv')
        self._init_model()
        self._init_bus()
        self.win = self.xml.get_widget('main')
        self.win.connect('delete-event', lambda self, e: gtk.main_quit())
        self.xml.signal_autoconnect(self)

    def _init_bus(self):
        bus = dbus.SessionBus()
        self.audbus_player = bus.get_object('org.atheme.audacious', '/Player')
        self.audbus_tracklist = bus.get_object('org.atheme.audacious', '/TrackList')

    def _init_model(self):
        h = adminbase.MUSIC_FIELDS_HEADERS
        self.ls = gtk.ListStore(str, str, str, str, str, str, str, bool)
        self.filter = self.ls.filter_new()
        self.filter.set_visible_column(7)
        self.tv.set_model(self.filter)
        self.tv_sel = self.tv.get_selection()
        self.tv_sel.set_mode(gtk.SELECTION_MULTIPLE)
        for i in range(len(h)):
            header_cell = gtk.CellRendererText()
            header_col = gtk.TreeViewColumn(h[i], header_cell, text=adminbase.MUSIC_FIELDS[h[i]])
            self.tv.append_column(header_col)
        for row in adminbase.get_table():
            row = list(row)
            row[adminbase.MUSIC_FIELDS['duration']] = self._nano2human(row[adminbase.MUSIC_FIELDS['duration']])
            uri = row.pop(0)
            #filename = urllib.unquote(uri)[7:]
            #filename = unicode(filename, 'utf-8')
            filename = get_local_path_from_uri(uri)
            row.insert(0, filename)
            row.append(True)
            self.ls.append(row)

    def import_data(self, data_list):
        for tag in data_list:
            mytag = list(tag)
            mytag[adminbase.MUSIC_FIELDS['duration']] = self._nano2human(mytag[adminbase.MUSIC_FIELDS['duration']])
            uri = mytag.pop(0)
            #filename = urllib.unquote(uri)[7:]
            filename = get_local_path_from_uri(uri)
            mytag.insert(0, filename)
            mytag.append(True)
            self.ls.append(mytag)
        self.filter.refilter()

    def _nano2human(self, time):
        time = long(time)
        h = time/3600000000000
        m = time/60000000000 - h
        s = time/1000000000 -h*3600 -m*60
        return '%sh : %2dm : %2ds' % (h, m, s)

    def _fetch_music(self, query):
        query_clean = adminbase.normalize(query)
        for row in self.ls:
            for col in row:
                try:
                    if col.lower().count(query_clean):
                        row[7] = True
                        break
                    else:
                        row[7] = False
                except: pass
        self.filter.refilter()

    #def search_entry_activate_cb(self, e): 
    #    self._fetch_music(e.get_text()) ##Uncomment this if searching on the fly is slow

    def search_entry_changed_cb(self, e):
        self._fetch_music(e.get_text())

    def play_clicked_cb(self, b):
        print 'pausing'
        self.audbus_player.Pause(dbus_interface = 'org.freedesktop.MediaPlayer')

    def add_media_clicked_cb(self, b):
        AddWindow(title='Add media to library', mainwin=self)
        
    def add_dir_clicked_cb(self, b):
        AddWindow(title='Add media folder to library', action=gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER, mainwin=self)

    def search_results_tv_row_activated_cb(self, tv, rp, c):
        self.audbus_tracklist.AddTrack(u'file://' + self.filter[rp][0], False)

    def enqueue_clicked_cb(self, b):
        model, paths = self.tv_sel.get_selected_rows()
        for p in paths:
            self.audbus_tracklist.AddTrack( 'file://' + model[p][0], False)

    def read_dbase_to_memory(self): #TODO: A more resources efficient approach is needed...
        """Read entire database to memory. Warning! If you have limited resources this could break your medialib"""
        table = adminbase.get_table()

if __name__ == '__main__':
    main = MainWindow()
    main.win.show_all()
    gtk.main()
